package com.webinsky.folder.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.webinsky.common.proj.DelFlag;
import com.webinsky.common.proj.Lang;
import com.webinsky.folder.domain.Folder;
import com.webinsky.folder.domain.FolderArticle;
import com.webinsky.folder.domain.FolderFilter;
import com.webinsky.folder.domain.FolderIndex;
import com.webinsky.folder.domain.FolderIndexCount;
import com.webinsky.folder.domain.FolderIndexCounts;
import com.webinsky.folder.domain.FolderRelationshipSync;
import com.webinsky.folder.domain.FolderRelationshipSync.FolderRelationship;
import com.webinsky.folder.domain.FolderType;
import com.webinsky.folder.domain.Folders;
import com.webinsky.folder.persist.dao.FolderBookIndexMapper;
import com.webinsky.folder.persist.dao.FolderCatalogMapper;
import com.webinsky.folder.persist.dao.FolderItemMapper;
import com.webinsky.folder.persist.dao.FolderMapper;
import com.webinsky.folder.persist.entity.FolderBookIndex;
import com.webinsky.folder.persist.entity.FolderCatalog;
import com.webinsky.folder.persist.entity.FolderItem;
import com.webinsky.folder.persist.entity.FolderView;
import com.webinsky.folder.service.FolderManagement;

@Service
public class FolderManagementImpl implements FolderManagement {
	// logger
	private static final Logger logger = LoggerFactory.getLogger(FolderManagementImpl.class);
	@Autowired
	private FolderItemMapper itemDao;
	@Autowired
	private FolderCatalogMapper catalogDao;
	@Autowired
	private FolderBookIndexMapper bookIndexDao;
	@Autowired
	private FolderMapper folderDao;
	
	private Folder convert(FolderItem item){
		Folder folder = new Folder();
		folder.setSiteId(item.getSiteId());
		folder.setId(item.getId());
		folder.setLanguage(Lang.parse(item.getLanguage()));
		folder.setName(item.getName());
		folder.setSort(item.getSort());
		return folder;
	}
	
	private Folder convert(FolderCatalog catalog) {
		Folder folder = new Folder();
		folder.setSiteId(catalog.getSiteId());
		folder.setId(catalog.getId());
		folder.setLanguage(Lang.parse(catalog.getLanguage()));
		folder.setName(catalog.getName());
		folder.setSort(catalog.getSort());
		return folder;
	}
	
//	private void syncHot(FolderRelationshipSync relationSync) {
//		List<FolderBookIndex> bookIndexes = bookIndexDao.selectByHotAndDel(relationSync.getBookMode().getId(), 1, DelFlag.UNDel.getFlag());
//		if ( bookIndexes.isEmpty() ){
//			return;
//		}
//		Map<String, Integer> cnSync = new HashMap<>();
//		bookIndexes.forEach( bkIndex -> {
//			for ( String key : relationSync.getCnArticles().keySet() ){
//				if ( relationSync.getCnArticles().get(key).intValue() == bkIndex.getArticleId() ){
//					cnSync.put(key, bkIndex.getArticleId());
//					break;
//				}
//			}
//		});
//		
//		if ( cnSync.isEmpty() ){
//			return;
//		}
//		
//		Map<String, List<FolderBookIndex>> langBookIndexes = bookIndexes.stream().collect(Collectors.groupingBy(FolderBookIndex::getLanguage));
//		List<FolderBookIndex> jpIndexes = langBookIndexes.get(Lang.jaJP.getLang());
//		List<FolderBookIndex> enIndexes = langBookIndexes.get(Lang.enUS.getLang());
//		List<FolderBookIndex> koIndexes = langBookIndexes.get(Lang.ko.getLang());
//		List<FolderBookIndex> thIndexes = langBookIndexes.get(Lang.th.getLang());
//		List<FolderBookIndex> twIndexes = langBookIndexes.get(Lang.zhTW.getLang());
//		List<FolderBookIndex> zhIndexes = langBookIndexes.get(Lang.zhCN.getLang());
//		Map<Integer, FolderBookIndex> zhIndexMap = zhIndexes.stream().collect(Collectors.toMap(FolderBookIndex::getArticleId, Function.identity()));
//		
//		cnSync.keySet().forEach(key -> {
//			int aId = cnSync.get(key);
//			FolderBookIndex zhIndex = zhIndexMap.get(aId);
//			// 日文
//			if ( relationSync.getJpArticles().get(key) != null ) {
//				boolean updated = false;
//				if ( jpIndexes != null ){
//					for ( FolderBookIndex fi : jpIndexes ){
//						if ( fi.getArticleId() == relationSync.getJpArticles().get(key) ){
//							fi.setSort(zhIndex.getSort());
//							bookIndexDao.updateByPrimaryKey(fi);
//							updated = true;
//						}
//					}
//				}
//				if ( !updated ){
//					FolderBookIndex record = new FolderBookIndex();
//					record.setArticleId(relationSync.getJpArticles().get(key));
//					record.setIsHot(1);
//					record.setSort(zhIndex.getSort());
//					record.setLanguage(Lang.jaJP.getLang());
//					record.setDel(DelFlag.UNDel.getFlag());
//					record.setBookId(relationSync.getBookMode().getId());
//					bookIndexDao.insert(record);
//				}
//				
//			}
//			// 英文
//			if ( relationSync.getEnArticles().get(key) != null ) {
//				
//				boolean updated = false;
//				if ( enIndexes != null ){
//					for ( FolderBookIndex fi : enIndexes ){
//						if ( fi.getArticleId() == relationSync.getEnArticles().get(key) ){
//							fi.setSort(zhIndex.getSort());
//							bookIndexDao.updateByPrimaryKey(fi);
//							updated = true;
//						}
//					}
//				}
//				if ( !updated ){
//					FolderBookIndex record = new FolderBookIndex();
//					record.setArticleId(relationSync.getEnArticles().get(key));
//					record.setIsHot(1);
//					record.setSort(zhIndex.getSort());
//					record.setLanguage(Lang.enUS.getLang());
//					record.setDel(DelFlag.UNDel.getFlag());
//					record.setBookId(relationSync.getBookMode().getId());
//					bookIndexDao.insert(record);
//				}
//				
//			}
//			// 繁体
//			if ( relationSync.getTwArticles().get(key) != null ) {
//				
//				boolean updated = false;
//				if ( twIndexes != null ){
//					for ( FolderBookIndex fi : twIndexes ){
//						if ( fi.getArticleId() == relationSync.getTwArticles().get(key) ){
//							fi.setSort(zhIndex.getSort());
//							bookIndexDao.updateByPrimaryKey(fi);
//							updated = true;
//						}
//					}
//				}
//				if ( !updated ){
//					FolderBookIndex record = new FolderBookIndex();
//					record.setArticleId(relationSync.getTwArticles().get(key));
//					record.setIsHot(1);
//					record.setSort(zhIndex.getSort());
//					record.setLanguage(Lang.zhTW.getLang());
//					record.setDel(DelFlag.UNDel.getFlag());
//					record.setBookId(relationSync.getBookMode().getId());
//					bookIndexDao.insert(record);
//				}
//				
//			}
//			// 泰文
//			if ( relationSync.getThArticles().get(key) != null ) {
//				
//				boolean updated = false;
//				if ( thIndexes != null ){
//					for ( FolderBookIndex fi : thIndexes ){
//						if ( fi.getArticleId() == relationSync.getThArticles().get(key) ){
//							fi.setSort(zhIndex.getSort());
//							bookIndexDao.updateByPrimaryKey(fi);
//							updated = true;
//						}
//					}
//				}
//				if ( !updated ){
//					FolderBookIndex record = new FolderBookIndex();
//					record.setArticleId(relationSync.getThArticles().get(key));
//					record.setIsHot(1);
//					record.setSort(zhIndex.getSort());
//					record.setLanguage(Lang.th.getLang());
//					record.setDel(DelFlag.UNDel.getFlag());
//					record.setBookId(relationSync.getBookMode().getId());
//					bookIndexDao.insert(record);
//				}
//				
//			}
//			// 韩文
//			if ( relationSync.getKrArticles().get(key) != null ) {
//				
//				boolean updated = false;
//				if ( koIndexes != null ){
//					for ( FolderBookIndex fi : koIndexes ){
//						if ( fi.getArticleId() == relationSync.getKrArticles().get(key) ){
//							fi.setSort(zhIndex.getSort());
//							bookIndexDao.updateByPrimaryKey(fi);
//							updated = true;
//						}
//					}
//				}
//				if ( !updated ){
//					FolderBookIndex record = new FolderBookIndex();
//					record.setArticleId(relationSync.getKrArticles().get(key));
//					record.setIsHot(1);
//					record.setSort(zhIndex.getSort());
//					record.setLanguage(Lang.ko.getLang());
//					record.setDel(DelFlag.UNDel.getFlag());
//					record.setBookId(relationSync.getBookMode().getId());
//					bookIndexDao.insert(record);
//				}
//			}
//		});
//	}
	
	
	private void syncCatalog(List<FolderRelationship> folderShips, FolderRelationshipSync relationSync) {
		List<Integer> cnCatalogIds = folderShips.stream().map(e -> e.cnId).collect(Collectors.toList());
		List<FolderBookIndex> folderCatalogBookIndexes = bookIndexDao.selectCatalogByDel(relationSync.getSiteId(), DelFlag.UNDel.getFlag());
		Map<String, List<FolderBookIndex>> langFolderIndex = folderCatalogBookIndexes.stream().collect(Collectors.groupingBy(FolderBookIndex::getLanguage));
		List<FolderBookIndex> cnbookIndexs = bookIndexDao.selectBySiteIdAndLang(relationSync.getSiteId(), Lang.zhCN.getLang(), DelFlag.UNDel.getFlag());
		List<FolderBookIndex> cnCatalogBookIndexs = cnbookIndexs.stream().filter(e -> cnCatalogIds.contains(e.getCatalogId())).collect(Collectors.toList());
		Map<Integer, List<FolderBookIndex>> cnCatalogBookIndexsMap = cnCatalogBookIndexs.stream().collect(Collectors.groupingBy(FolderBookIndex::getCatalogId));
		List<FolderCatalog> folderCatalogs = catalogDao.selectBySiteIdAndDel(relationSync.getSiteId(), DelFlag.UNDel.getFlag());
		Map<String, FolderCatalog> jpFolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.jaJP.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderCatalog::getName, Function.identity()));
		Map<String, FolderCatalog> enFolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.enUS.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderCatalog::getName, Function.identity()));
		Map<String, FolderCatalog> krFolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.ko.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderCatalog::getName, Function.identity()));
		Map<String, FolderCatalog> thFolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.th.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderCatalog::getName, Function.identity()));
		Map<String, FolderCatalog> zhTWFolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.zhTW.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderCatalog::getName, Function.identity()));
		List<FolderCatalog> cnfolderCatalogs = folderCatalogs.stream().filter(it -> it.getLanguage().equals(Lang.zhCN.getLang())).collect(Collectors.toList());
		cnfolderCatalogs.forEach( cnCatalog -> {
			FolderCatalog jpCatalog = jpFolderCatalogs.get(cnCatalog.getName());
			FolderCatalog enCatalog = enFolderCatalogs.get(cnCatalog.getName());
			FolderCatalog krCatalog = krFolderCatalogs.get(cnCatalog.getName());
			FolderCatalog thCatalog = thFolderCatalogs.get(cnCatalog.getName());
			FolderCatalog twCatalog = zhTWFolderCatalogs.get(cnCatalog.getName());
			if ( jpCatalog != null ) {
				jpCatalog.setSort(cnCatalog.getSort());
				catalogDao.updateByPrimaryKey(jpCatalog);
			}
			if ( enCatalog != null ) {
				enCatalog.setSort(cnCatalog.getSort());
				catalogDao.updateByPrimaryKey(enCatalog);
			}
			if ( krCatalog != null ) {
				krCatalog.setSort(cnCatalog.getSort());
				catalogDao.updateByPrimaryKey(krCatalog);
			}
			if ( thCatalog != null ) {
				thCatalog.setSort(cnCatalog.getSort());
				catalogDao.updateByPrimaryKey(thCatalog);
			}
			if ( twCatalog != null ) {
				twCatalog.setSort(cnCatalog.getSort());
				catalogDao.updateByPrimaryKey(twCatalog);
			}
		});
		
		for ( FolderRelationship folderShip : folderShips ) {
			List<FolderBookIndex> cnSelectBookindexs = cnCatalogBookIndexsMap.get(folderShip.cnId);
			if ( cnSelectBookindexs == null ){
				continue;
			}
			Map<Integer, FolderBookIndex> cnSelectBookMap = cnSelectBookindexs.stream().collect(Collectors.toMap(FolderBookIndex::getArticleId, Function.identity()));
			List<Integer> cnarticleIds = cnSelectBookindexs.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
			List<String> cnname = new ArrayList<>();
			relationSync.getCnArticles().forEach((k, v) -> {
				if ( cnarticleIds.contains(v) ) {
					cnname.add(k);
				}
			});
			// 日文
			if ( folderShip.jpId > 0 ) {
				List<FolderBookIndex> jpBookIndexes = langFolderIndex.get(Lang.jaJP.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
		
					if ( relationSync.getJpArticles().get(e) != null) {						
						boolean updated = false;
						
						if ( jpBookIndexes != null ){
							for ( FolderBookIndex fi : jpBookIndexes ){
								if ( fi.getCatalogId() == folderShip.jpId && fi.getArticleId() == relationSync.getJpArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getJpArticles().get(e));
						record.setCatalogId(folderShip.jpId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.jaJP.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 英文
			if ( folderShip.enId > 0 ) {
				List<FolderBookIndex> enBookIndexes = langFolderIndex.get(Lang.enUS.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getEnArticles().get(e) != null) {
						boolean updated = false;
						
						if ( enBookIndexes != null ){
							for ( FolderBookIndex fi : enBookIndexes ){
								if ( fi.getCatalogId() == folderShip.enId && fi.getArticleId() == relationSync.getEnArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getEnArticles().get(e));
						record.setCatalogId(folderShip.enId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.enUS.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 韩文
			if ( folderShip.krId > 0 ) {
				List<FolderBookIndex> krBookIndexes = langFolderIndex.get(Lang.ko.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getKrArticles().get(e) != null) {
						boolean updated = false;
						
						if ( krBookIndexes != null ){
							for ( FolderBookIndex fi : krBookIndexes ){
								if ( fi.getCatalogId() == folderShip.krId && fi.getArticleId() == relationSync.getKrArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getKrArticles().get(e));
						record.setCatalogId(folderShip.krId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.ko.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 泰文
			if ( folderShip.thId > 0 ){
				List<FolderBookIndex> thBookIndexes = langFolderIndex.get(Lang.th.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getThArticles().get(e) != null) {
						boolean updated = false;
						if ( thBookIndexes != null ){
							for ( FolderBookIndex fi : thBookIndexes ){
								if ( fi.getCatalogId() == folderShip.thId && fi.getArticleId() == relationSync.getThArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getThArticles().get(e));
						record.setCatalogId(folderShip.thId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.th.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 繁体
			if ( folderShip.twId > 0 ){
				List<FolderBookIndex> twBookIndexes = langFolderIndex.get(Lang.zhTW.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getTwArticles().get(e) != null) {
						boolean updated = false;
						
						if ( twBookIndexes != null ){
							for ( FolderBookIndex fi : twBookIndexes ){
								if ( fi.getCatalogId() == folderShip.twId && fi.getArticleId() == relationSync.getTwArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getTwArticles().get(e));
						record.setCatalogId(folderShip.twId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.zhTW.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}			
		}
	}
	
	
	private void syncItem(List<FolderRelationship> folderShips, FolderRelationshipSync relationSync) {
		List<Integer> cnItemIds = folderShips.stream().map(e -> e.cnId).collect(Collectors.toList());
		List<FolderBookIndex> folderItemBookIndexes = bookIndexDao.selectItemByDel(relationSync.getSiteId(), DelFlag.UNDel.getFlag());
		Map<String, List<FolderBookIndex>> langFolderIndex = folderItemBookIndexes.stream().collect(Collectors.groupingBy(FolderBookIndex::getLanguage));
		List<FolderBookIndex> cnbookIndexs = bookIndexDao.selectBySiteIdAndLang(relationSync.getSiteId(), Lang.zhCN.getLang(), DelFlag.UNDel.getFlag());
		List<FolderBookIndex> cnItemBookIndexs = cnbookIndexs.stream().filter(e -> cnItemIds.contains(e.getItemId())).collect(Collectors.toList());
		Map<Integer, List<FolderBookIndex>> cnItemBookIndexsMap = cnItemBookIndexs.stream().collect(Collectors.groupingBy(FolderBookIndex::getItemId));
		List<FolderItem> folderItems = itemDao.selectBySiteIdAndDel(relationSync.getSiteId(), DelFlag.UNDel.getFlag());
		Map<String, FolderItem> jpFolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.jaJP.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderItem::getName, Function.identity()));
		Map<String, FolderItem> enFolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.enUS.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderItem::getName, Function.identity()));
		Map<String, FolderItem> krFolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.ko.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderItem::getName, Function.identity()));
		Map<String, FolderItem> thFolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.th.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderItem::getName, Function.identity()));
		Map<String, FolderItem> zhTWFolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.zhTW.getLang())).collect(Collectors.toList()).stream().collect(Collectors.toMap(FolderItem::getName, Function.identity()));
		List<FolderItem> cnfolderItems = folderItems.stream().filter(it -> it.getLanguage().equals(Lang.zhCN.getLang())).collect(Collectors.toList());
		cnfolderItems.forEach( cnItem -> {
			FolderItem jpItem = jpFolderItems.get(cnItem.getName());
			FolderItem enItem = enFolderItems.get(cnItem.getName());
			FolderItem krItem = krFolderItems.get(cnItem.getName());
			FolderItem thItem = thFolderItems.get(cnItem.getName());
			FolderItem twItem = zhTWFolderItems.get(cnItem.getName());
			if ( jpItem != null ) {
				jpItem.setSort(cnItem.getSort());
				itemDao.updateByPrimaryKey(jpItem);
			}
			if ( enItem != null ) {
				enItem.setSort(cnItem.getSort());
				itemDao.updateByPrimaryKey(enItem);
			}
			if ( krItem != null ) {
				krItem.setSort(cnItem.getSort());
				itemDao.updateByPrimaryKey(krItem);
			}
			if ( thItem != null ) {
				thItem.setSort(cnItem.getSort());
				itemDao.updateByPrimaryKey(thItem);
			}
			if ( twItem != null ) {
				twItem.setSort(cnItem.getSort());
				itemDao.updateByPrimaryKey(twItem);
			}
		});
		for ( FolderRelationship folderShip : folderShips ) {
			List<FolderBookIndex> cnSelectBookindexs = cnItemBookIndexsMap.get(folderShip.cnId);
			if ( cnSelectBookindexs == null ){
				continue;
			}
			Map<Integer, FolderBookIndex> cnSelectBookMap = cnSelectBookindexs.stream().collect(Collectors.toMap(FolderBookIndex::getArticleId, Function.identity()));
			List<Integer> cnarticleIds = cnSelectBookindexs.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
			List<String> cnname = new ArrayList<>();
			relationSync.getCnArticles().forEach((k, v) -> {
				if ( cnarticleIds.contains(v) ) {
					cnname.add(k);
				}
			});
			// 日文
			if ( folderShip.jpId > 0 ) {
				List<FolderBookIndex> jpBookIndexes = langFolderIndex.get(Lang.jaJP.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getJpArticles().get(e) != null) {
						boolean updated = false;
						if ( jpBookIndexes != null ){
							for ( FolderBookIndex fi : jpBookIndexes ){
								if ( fi.getItemId() == folderShip.jpId && fi.getArticleId() == relationSync.getJpArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getJpArticles().get(e));
						record.setItemId(folderShip.jpId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.jaJP.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 英文
			if ( folderShip.enId > 0 ) {
				List<FolderBookIndex> enBookIndexes = langFolderIndex.get(Lang.enUS.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getEnArticles().get(e) != null) {
						boolean updated = false;
						
						if ( enBookIndexes != null ){
							for ( FolderBookIndex fi : enBookIndexes ){
								if ( fi.getItemId() == folderShip.enId && fi.getArticleId() == relationSync.getEnArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getEnArticles().get(e));
						record.setItemId(folderShip.enId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.enUS.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 韩文
			if ( folderShip.krId > 0 ) {
				List<FolderBookIndex> krBookIndexes = langFolderIndex.get(Lang.ko.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getKrArticles().get(e) != null) {
						boolean updated = false;
						
						if ( krBookIndexes != null ){
							for ( FolderBookIndex fi : krBookIndexes ){
								if ( fi.getItemId() == folderShip.krId && fi.getArticleId() == relationSync.getKrArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getKrArticles().get(e));
						record.setItemId(folderShip.krId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.ko.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 泰文
			if ( folderShip.thId > 0 ){
				List<FolderBookIndex> thBookIndexes = langFolderIndex.get(Lang.th.getLang());
				cnname.forEach( e -> {
					int aId = relationSync.getCnArticles().get(e);
					FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
					
					if ( relationSync.getThArticles().get(e) != null) {
						boolean updated = false;
						
						if ( thBookIndexes != null ){
							for ( FolderBookIndex fi : thBookIndexes ){
								if ( fi.getItemId() == folderShip.thId && fi.getArticleId() == relationSync.getThArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getThArticles().get(e));
						record.setItemId(folderShip.thId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.th.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
			// 繁体
			if ( folderShip.twId > 0 ){
				List<FolderBookIndex> twBookIndexes = langFolderIndex.get(Lang.zhTW.getLang());
				cnname.forEach( e -> {
					if ( relationSync.getTwArticles().get(e) != null) {
						int aId = relationSync.getCnArticles().get(e);
						FolderBookIndex cnFolderBookIndex = cnSelectBookMap.get(aId);
						
						boolean updated = false;
						if ( twBookIndexes != null ){
							
							for ( FolderBookIndex fi : twBookIndexes ){
								if ( fi.getItemId() == folderShip.twId && fi.getArticleId() == relationSync.getTwArticles().get(e) ){
									fi.setSort(cnFolderBookIndex.getSort());
									bookIndexDao.updateByPrimaryKey(fi);
									updated = true;
								}
							}
						}
						if ( updated ){
							return;
						}
						
						FolderBookIndex record = new FolderBookIndex();
						record.setArticleId(relationSync.getTwArticles().get(e));
						record.setItemId(folderShip.twId);
						record.setSort(cnFolderBookIndex.getSort());
						record.setLanguage(Lang.zhTW.getLang());
						record.setDel(DelFlag.UNDel.getFlag());
						record.setSiteId(relationSync.getSiteId());
						bookIndexDao.insert(record);
					}
				});
			}
		}
	}
	
	private FolderItem convertItem(Folder folder){
		FolderItem item = new FolderItem();
		item.setName(folder.getName());
		item.setSort(folder.getSort());
		item.setSiteId(folder.getSiteId());
		item.setLanguage(folder.getLanguage().getLang());
		return item;
	}
	
	private Folder convertItem(FolderItem item){
		Folder folder = new Folder();
		folder.setId(item.getId());
		folder.setItemId(item.getId());
		folder.setType(FolderType.Item);
		folder.setName(item.getName());
		folder.setSiteId(item.getSiteId());
		folder.setLanguage(Lang.parse(item.getLanguage()));
		folder.setSort(item.getSort());
		return folder;
	}
	
	private FolderCatalog convertCatalog(Folder folder){
		FolderCatalog catalog = new FolderCatalog();
		catalog.setName(folder.getName());
		catalog.setSort(folder.getSort());
		catalog.setSiteId(folder.getSiteId());
		catalog.setLanguage(folder.getLanguage().getLang());
		return catalog;
	}
	
	private Folder convertCatalog(FolderCatalog catalog){
		Folder folder = new Folder();
		folder.setId(catalog.getId());
		folder.setItemId(catalog.getItemId());
		folder.setType(FolderType.Category);
		folder.setName(catalog.getName());
		folder.setSiteId(catalog.getSiteId());
		folder.setLanguage(Lang.parse(catalog.getLanguage()));
		folder.setSort(catalog.getSort());
		return folder;
	}
	
	private Folder convertView(FolderView view){
		Folder folder = new Folder();
		folder.setId(view.getId());
		folder.setType(FolderType.parse(view.getType()));
		folder.setName(view.getName());
		return folder;
	}
	
	
	@Override
	public void addFolder(Folder folder) {
		logger.info("[add Foler] beign");
		if ( folder != null && folder.getType() != null ){
			if ( folder.getType() == FolderType.Category){
				FolderCatalog folderCatalog = convertCatalog(folder);
				folderCatalog.setDel(DelFlag.UNDel.getFlag());
				folderCatalog.setItemId(folder.getItemId());
				catalogDao.insert(folderCatalog);
				folder.setId(folderCatalog.getId());
			} else if ( folder.getType() == FolderType.Item){
				FolderItem item = convertItem(folder);
				item.setDel(DelFlag.UNDel.getFlag());
				itemDao.insert(item);
				folder.setId(item.getId());
			} else {
				logger.info("[add Foler] impossible folder type");
			}
		}
		logger.info("[add folder] end");
	}

	@Override
	public void deleteFolder(int folderId, FolderType type) {
		if ( folderId > 0 && type != null ){
			switch ( type ){
				case Category: {
					FolderCatalog catalog = catalogDao.selectById(folderId);
					if ( catalog != null ){
						catalog.setDel(DelFlag.Del.getFlag());
						catalog.setUpdateAt(new Date());
						catalogDao.updateByPrimaryKey(catalog);
						List<FolderBookIndex> indexes = bookIndexDao.selectByCatalogIdAndDel(catalog.getId(), DelFlag.UNDel.getFlag());
						indexes.forEach(e -> {
							e.setDel(DelFlag.Del.getFlag());
							e.setUpdateAt(new Date());
							bookIndexDao.updateByPrimaryKey(e);
						});
					}
					break;
				}
				case Item:{
					FolderItem item = itemDao.selectById(folderId);
					if ( item != null ){
						item.setDel(DelFlag.Del.getFlag());
						item.setUpdateAt(new Date());
						itemDao.updateByPrimaryKey(item);
						List<FolderBookIndex> indexes = bookIndexDao.selectByCatalogIdAndDel(item.getId(), DelFlag.UNDel.getFlag());
						indexes.forEach(e -> {
							e.setDel(DelFlag.Del.getFlag());
							e.setUpdateAt(new Date());
							bookIndexDao.updateByPrimaryKey(e);
						});
					}
				}
				default: {
					logger.info("[deleteFolder] impossible folder type");
				}
			}
		}
	}

	@Override
	public void changeFolderName(int folderId, FolderType type, String name) {
		if ( folderId > 0 && type != null && name != null ){
			switch ( type ){
				case Item: {
					FolderItem item = itemDao.selectById(folderId);
					if ( item != null ){
						item.setName(name);
						item.setUpdateAt(new Date());
						itemDao.updateByPrimaryKey(item);
					}
					break;
				}
				case Category: {
					FolderCatalog catalog = catalogDao.selectById(folderId);
					if ( catalog != null ){
						catalog.setName(name);
						catalog.setUpdateAt(new Date());
						catalogDao.updateByPrimaryKey(catalog);
					}
				}
				default:
			}
		}
	}

	@Override
	public void addArtileToFolder(int folderId, FolderType type, List<FolderArticle> articles) {
		if ( folderId > 0 && type != null && articles != null ){
			switch ( type ){
				case Item: {
					// 检查是否重复
					List<FolderBookIndex> bookIndex = bookIndexDao.selectByItemIdAndDel(folderId, DelFlag.UNDel.getFlag());
					if ( !bookIndex.isEmpty() ){
						List<Integer> articleIds = bookIndex.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
						List<Integer> newAricleIds = articles.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
						for ( Integer id : articleIds ){
							if ( newAricleIds.contains(id) ){
								throw new RuntimeException("code=2005");
							}
						}
					}
					articles.forEach(article ->{
						FolderBookIndex index = new FolderBookIndex();
						index.setArticleId(article.getArticleId());
						index.setSiteId(article.getSiteId());
						index.setItemId(folderId);
						index.setDel(DelFlag.UNDel.getFlag());
						index.setLanguage(article.getLang().getLang());
						index.setSort(article.getSort());
						bookIndexDao.insert(index);
						article.setId(index.getId());
					});
					break;
				}
				case Category: {
					// 检查是否重复
					List<FolderBookIndex> bookIndex = bookIndexDao.selectByCatalogIdAndDel(folderId, DelFlag.UNDel.getFlag());
					if ( !bookIndex.isEmpty() ){
						List<Integer> articleIds = bookIndex.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
						List<Integer> newAricleIds = articles.stream().map(e -> e.getArticleId()).collect(Collectors.toList());
						for ( Integer id : articleIds ){
							if ( newAricleIds.contains(id) ){
								throw new RuntimeException("code=2005");
							}
						}
					}
					articles.forEach(article ->{
						FolderBookIndex index = new FolderBookIndex();
						index.setArticleId(article.getArticleId());
						index.setSiteId(article.getSiteId());
						index.setCatalogId(folderId);
						index.setDel(DelFlag.UNDel.getFlag());
						index.setLanguage(article.getLang().getLang());
						index.setSort(article.getSort());
						bookIndexDao.insert(index);
						article.setId(index.getId());
					});
					break;
				}
				default:
				}
		}
	}

	@Override
	public List<FolderIndex> getFolderIndex(int siteId, Lang lang) {
		List<FolderIndex> folderIndex = new ArrayList<>();
		if ( siteId > 0 && lang != null ){
			List<FolderBookIndex> indexes = bookIndexDao.selectBySiteIdAndLang(siteId, lang.getLang(), DelFlag.UNDel.getFlag());
			if ( !indexes.isEmpty() ) {
				// cataglog 查找
				List<FolderBookIndex> catalogIndexs = indexes.stream().filter(e -> e.getCatalogId() > 0).collect(Collectors.toList());
				if ( !catalogIndexs.isEmpty() ){
					Map<Integer, List<FolderBookIndex>> catalogFolder = catalogIndexs.stream().collect(Collectors.groupingBy(FolderBookIndex::getCatalogId));
					List<Integer> catalogIds = catalogFolder.keySet().stream().collect(Collectors.toList());
					List<FolderCatalog> folderCatalogs = catalogDao.selectByIds(catalogIds);
					if ( !catalogIndexs.isEmpty() ){
						folderCatalogs.forEach(c -> {
							FolderIndex index = new FolderIndex();
							index.setFolderId(c.getId());
							index.setFolderName(c.getName());
							index.setSiteId(c.getSiteId());
							index.setLanguage(lang);
							index.setType(FolderType.Category);
							if ( catalogFolder.get(c.getId()) != null ){
								List<FolderArticle> articles = new ArrayList<>();
								catalogFolder.get(c.getId()).forEach(l -> {
									FolderArticle fa = new FolderArticle();
									fa.setArticleId(l.getArticleId());
									//fa.setArticleTile(articleTile);
									fa.setSort(l.getSort());
									fa.setId(l.getId());
									fa.setFolderId(l.getCatalogId());
									fa.setType(FolderType.Category);
									articles.add(fa);
								});
								index.setArticles(articles);
							}
							folderIndex.add(index);
						});
					}
				}
				// item 查找
				List<FolderBookIndex> itemIndexs = indexes.stream().filter(e -> e.getItemId() > 0).collect(Collectors.toList());
				if ( !itemIndexs.isEmpty() ){
					Map<Integer, List<FolderBookIndex>> itemFolder = itemIndexs.stream().collect(Collectors.groupingBy(FolderBookIndex::getItemId));
					List<Integer> itemIds = itemFolder.keySet().stream().collect(Collectors.toList());
					List<FolderItem> folderItems = itemDao.selectByIds(itemIds);
					folderItems.forEach(c -> {
						FolderIndex index = new FolderIndex();
						index.setFolderId(c.getId());
						index.setFolderName(c.getName());
						index.setSiteId(c.getSiteId());
						index.setLanguage(lang);
						index.setType(FolderType.Item);
						if ( itemFolder.get(c.getId()) != null ){
							List<FolderArticle> articles = new ArrayList<>();
							itemFolder.get(c.getId()).forEach(l -> {
								FolderArticle fa = new FolderArticle();
								fa.setArticleId(l.getArticleId());
								//fa.setArticleTile(articleTile);
								fa.setId(l.getId());
								fa.setSort(l.getSort());
								fa.setFolderId(l.getItemId());
								fa.setType(FolderType.Item);
								articles.add(fa);
							});
							index.setArticles(articles);
						}
						folderIndex.add(index);
					});
				}
			}
		}
		return folderIndex;
	}

	@Override
	public void deleteArticleFromFolder(int folderId, FolderType type, List<Integer> articleIds) {
		if ( folderId > 0 && type != null && articleIds != null ){
			switch ( type ){
				case Item:{
					List<FolderBookIndex> index = bookIndexDao.selectByItemIdAndDel(folderId, DelFlag.UNDel.getFlag());
					index.forEach( in -> {
						if ( articleIds.contains(in.getArticleId()) ){
							in.setDel(DelFlag.Del.getFlag());
							in.setUpdateAt(new Date());
							bookIndexDao.updateByPrimaryKey(in);
						}
					});
					break;
				}
				case Category:{
					List<FolderBookIndex> index = bookIndexDao.selectByCatalogIdAndDel(folderId, DelFlag.UNDel.getFlag());
					index.forEach( in -> {
						if ( articleIds.contains(in.getArticleId()) ){
							in.setDel(DelFlag.Del.getFlag());
							in.setUpdateAt(new Date());
							bookIndexDao.updateByPrimaryKey(in);
						}
					});
					break;
				}
				default:
			}
		}
	}

	@Override
	public Folders getFoldersByFilter(FolderFilter filter) {
		if ( filter != null ){
			Folders folders = new Folders();
			// 有类型选择的时候
			if ( filter.getType() != null ){
				if ( filter.getType() ==  FolderType.Item){
					List<FolderItem> items = itemDao.selectBySiteIdNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId(), filter.getSize(), filter.getStart());
					if ( items.size() > 0 ){
						items.forEach(e -> folders.getFolders().add(convertItem(e)));
						folders.setTotalSize(itemDao.selectCountByBookNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId()));
					}
				} else {
					List<FolderCatalog> catalog = catalogDao.selectBySiteIdNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId(), filter.getSize(), filter.getStart());
					if ( catalog.size() > 0 ){
						catalog.forEach(e -> folders.getFolders().add(convertCatalog(e)));
						folders.setTotalSize(catalogDao.selectCountBySiteIdNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId()));
					}
				}
			}
			// 选择all的时候
			else {
				List<FolderView> folderView = folderDao.selectViewByBookNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId(), filter.getSize(), filter.getStart());
				if ( !folderView.isEmpty() ){
					folderView.forEach(e -> folders.getFolders().add(convertView(e)));
					folders.setTotalSize(folderDao.selectCountByBookNameAndDel(filter.getFolderName(), DelFlag.UNDel.getFlag(), filter.getLanguage(), filter.getSiteId()));
				}
			}
			return folders;
		}
		return null;
	}

	@Override
	public void moveArtilePos(int siteId, int arctileId, int sort, FolderType type, int folderId) {
		if ( arctileId > 0 && sort >= 0 && folderId > 0 && type != null ){
			List<FolderBookIndex> itemIndex = null;
			switch ( type ){
			case Category:{
				itemIndex = bookIndexDao.selectByCatalogIdAndDel(folderId, DelFlag.UNDel.getFlag());
				break;
			}
			case Item:{
				itemIndex = bookIndexDao.selectByItemIdAndDel(folderId, DelFlag.UNDel.getFlag());
				break;
			}
			default: {
				
			}
			}
			if ( itemIndex != null ){
				itemIndex.forEach(e -> {
					if ( e.getArticleId() == arctileId ){
						e.setSort(sort);
						e.setUpdateAt(new Date());
						bookIndexDao.updateByPrimaryKey(e);
					}
				});
			}
		}
		
	}

	@Override
	public void deleteArticleFromFolder(int articleId) {
		if ( articleId > 0 ){
			List<FolderBookIndex> index = bookIndexDao.selectByArticleIdAndDel(articleId, DelFlag.UNDel.getFlag());
			index.forEach(e -> {
				e.setDel(DelFlag.Del.getFlag());
				e.setUpdateAt(new Date());
				bookIndexDao.updateByPrimaryKey(e);
			});
		}
	}

	@Override
	public void moveFolderPos(int folderId, int sort, FolderType type) {
		if ( folderId > 0 && sort >= 0 && type != null ) {
			switch ( type ) {
			case Category: {
				FolderCatalog folder = catalogDao.selectById(folderId);
				if ( folder != null ) {
					folder.setSort(sort);
					folder.setUpdateAt(new Date());
					catalogDao.updateByPrimaryKey(folder);
				}
				break;
			}
			case Item: {
				FolderItem item = itemDao.selectById(folderId);
				if ( item != null ) {
					item.setSort(sort);
					item.setUpdateAt(new Date());
					itemDao.updateByPrimaryKey(item);
				}
				break;
			}
			default: {
				
			}
			}
		}
	}

	@Override
	public void addFolders(List<Folder> folders, int siteId, FolderType type) {
		if ( siteId > 0 && type != null && folders != null ) {
			folders.forEach( folder -> {
				folder.setSiteId(siteId);
				folder.setType(type);
				addFolder(folder);
			});
		}
	}

	@Override
	public void syncRelationship(FolderRelationshipSync relationSync) {
		if ( relationSync != null ) {
			relationSync.getShips().forEach( (type, ships) -> {
				if ( type.equals("item") ) {
					syncItem(ships, relationSync);
				} else if (  type.equals("catalog")  ) {
					syncCatalog(ships, relationSync);
				}
			});
		}
	}


	@Override
	public void updateFolders(List<Folder> folders) {
		if ( folders == null || folders.isEmpty() ) {
			return;
		}
		folders.forEach(f -> {
			changeFolderName(f.getId(), f.getType(), f.getName());
		});
		
	}


	@Override
	public Folders getFoldersByIds(List<Integer> ids, FolderType type) {
		if ( ids == null || ids.isEmpty() || type == null ){
			return null;
		}
		Folders f = new Folders();
		if ( type == FolderType.Item){
			List<FolderItem> folderItems = itemDao.selectByIds(ids);
			folderItems.forEach(e -> {
				Folder itemFolder = convert(e);
				itemFolder.setType(FolderType.Item);
				f.getFolders().add(itemFolder);				
			});
		} else if ( type == FolderType.Category){
			List<FolderCatalog> folderCatagory = catalogDao.selectByIds(ids);
			folderCatagory.forEach(e -> {
				Folder catalogFolder = convert(e);
				catalogFolder.setType(FolderType.Category);
				f.getFolders().add(catalogFolder);				
			});
		}
		return f;
	}

	@Override
	public FolderIndexCounts getAllIndexes(Lang lang, int siteId) {
		if ( lang == null || siteId <= 0 ) {
			return new FolderIndexCounts();
		}
		// 取得所有一级，二级目录的文章
		List<FolderBookIndex> indexes = bookIndexDao.selectBySiteIdAndLang(siteId, lang.getLang(), DelFlag.UNDel.getFlag());
		if ( indexes.isEmpty() ) {
			return new FolderIndexCounts();
		}
		// 取得一级目录数据
		List<FolderItem> items = itemDao.selectBySiteLangAndDel(lang.getLang(), siteId, DelFlag.UNDel.getFlag());
		if ( items.isEmpty() ) {
			return new FolderIndexCounts();
		}
		FolderIndexCounts indexCounts = new FolderIndexCounts();
		indexCounts.setLang(lang);
		indexCounts.setSiteId(siteId);
		// 取得二级目录的数据
		List<FolderCatalog> catalogs = catalogDao.selectBySiteLangAndDel(siteId, lang.getLang(), DelFlag.UNDel.getFlag());
		Map<Integer, Integer> itemArticleCount = new HashMap<>();
		Map<Integer, Integer> catalogArticleCount = new HashMap<>();
		for ( FolderBookIndex fbi : indexes ) {
			// 统计二级目录下的文章数量
			if ( fbi.getCatalogId() > 0 ) {
				if ( catalogArticleCount.get(fbi.getCatalogId()) == null ) {
					catalogArticleCount.put(fbi.getCatalogId(), 0);
				}
				catalogArticleCount.put(fbi.getCatalogId(), catalogArticleCount.get(fbi.getCatalogId()) + 1);
			}
			// 如果二级目录ID小于等于0, 统计一级目录是否有数据
			else if ( fbi.getItemId() > 0 ) {
				if ( itemArticleCount.get(fbi.getItemId()) == null ) {
					itemArticleCount.put(fbi.getItemId(), 0);
				}
				itemArticleCount.put(fbi.getItemId(), itemArticleCount.get(fbi.getItemId()) + 1);
			}
		}
		Map<Integer, List<FolderCatalog>> itemCatalogMap = catalogs.stream().collect(Collectors.groupingBy(FolderCatalog::getItemId));
		for ( FolderItem fi : items ) {
			// 取得一级目录下的article数量
			int count = itemArticleCount.get(fi.getId()) == null ? 0 : itemArticleCount.get(fi.getId());
			int fcCount = 0;
			// 取得这个目录下的二级目录下的article数量
			List<FolderCatalog> fc = itemCatalogMap.get(fi.getId());
			if ( fc != null && !fc.isEmpty() ) {
				for ( FolderCatalog f : fc ) {
					if ( catalogArticleCount.get(f.getId()) != null ) {
						fcCount = fcCount + catalogArticleCount.get(f.getId());
					}
				}
			}
			FolderIndexCount indexCount = new FolderIndexCount();
			indexCount.setFolderId(fi.getId());
			indexCount.setFolderName(fi.getName());
			indexCount.setType(FolderType.Item);
			indexCount.setCount(count + fcCount);
			indexCounts.getCounts().add(indexCount);
		}
		
		return indexCounts;
	}

	@Override
	public List<Integer> getCatalogIdByItemId(int itemId, Lang lang, int siteId) {
		if ( itemId <= 0 ) {
			return new ArrayList<>(); 
		}
		List<FolderCatalog> catalogs = catalogDao.selectByItemIdLangAndDel(itemId, lang.getLang(), DelFlag.UNDel.getFlag(), siteId);
		return catalogs.stream().map(e -> e.getId()).collect(Collectors.toList());
	}
}
